int xc_sched_id(int xc_handle,
int *sched_id);
-int xc_domain_setinitialmem(int xc_handle,
- u32 domid,
- unsigned int initial_memkb);
-
int xc_domain_setmaxmem(int xc_handle,
u32 domid,
unsigned int max_memkb);
float cpu_weight,
u32 *pdomid)
{
- int err;
+ int err, errno_saved;
dom0_op_t op;
op.cmd = DOM0_CREATEDOMAIN;
op.u.createdomain.domain = (domid_t)*pdomid;
- op.u.createdomain.memory_kb = mem_kb;
- op.u.createdomain.cpu = cpu;
+ if ( (err = do_dom0_op(xc_handle, &op)) != 0 )
+ return err;
- if ( (err = do_dom0_op(xc_handle, &op)) == 0 )
+ *pdomid = (u16)op.u.createdomain.domain;
+
+ if ( (cpu != -1) &&
+ ((err = xc_domain_pincpu(xc_handle, *pdomid, cpu)) != 0) )
+ goto fail;
+
+ if ( (err = xc_domain_setcpuweight(xc_handle, *pdomid, cpu_weight)) != 0 )
+ goto fail;
+
+ if ( (err = xc_domain_setmaxmem(xc_handle, *pdomid, mem_kb)) != 0 )
+ goto fail;
+
+ if ( (err = do_dom_mem_op(xc_handle, MEMOP_increase_reservation,
+ NULL, mem_kb/4, 0, *pdomid)) != (mem_kb/4) )
{
- *pdomid = (u16)op.u.createdomain.domain;
-
- err = xc_domain_setcpuweight(xc_handle, *pdomid, cpu_weight);
+ if ( err > 0 )
+ errno = ENOMEM;
+ err = -1;
+ goto fail;
}
return err;
+
+ fail:
+ errno_saved = errno;
+ (void)xc_domain_destroy(xc_handle, *pdomid);
+ errno = errno_saved;
+ return err;
}
return ret;
}
-
-int xc_domain_setinitialmem(int xc_handle,
- u32 domid,
- unsigned int initial_memkb)
-{
- dom0_op_t op;
- op.cmd = DOM0_SETDOMAININITIALMEM;
- op.u.setdomaininitialmem.domain = (domid_t)domid;
- op.u.setdomaininitialmem.initial_memkb = initial_memkb;
- return do_dom0_op(xc_handle, &op);
-}
-
int xc_domain_setmaxmem(int xc_handle,
u32 domid,
unsigned int max_memkb)
static inline int do_dom0_op(int xc_handle, dom0_op_t *op)
{
- int ret = -1, retries = 0;
+ int ret = -1, errno_saved;
privcmd_hypercall_t hypercall;
op->interface_version = DOM0_INTERFACE_VERSION;
goto out1;
}
- again:
if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 )
{
- if ( (errno == EAGAIN) && (retries++ < 10) )
- {
- /*
- * This was added for memory allocation, where we can get EAGAIN
- * if memory is unavailable because it is on the scrub list.
- */
- sleep(1);
- goto again;
- }
if ( errno == EACCES )
fprintf(stderr, "Dom0 operation failed -- need to"
" rebuild the user-space tool set?\n");
- goto out2;
}
- out2: (void)munlock(op, sizeof(*op));
- out1: return ret;
+ errno_saved = errno;
+ (void)munlock(op, sizeof(*op));
+ errno = errno_saved;
+
+ out1:
+ return ret;
}
static inline int do_dom_mem_op(int xc_handle,
{
privcmd_hypercall_t hypercall;
long ret = -EINVAL;
-
+ int errno_saved;
+
hypercall.op = __HYPERVISOR_dom_mem_op;
hypercall.arg[0] = (unsigned long)memop;
hypercall.arg[1] = (unsigned long)extent_list;
hypercall.arg[3] = (unsigned long)extent_order;
hypercall.arg[4] = (unsigned long)domid;
- if ( mlock(extent_list, nr_extents*sizeof(unsigned long)) != 0 )
+ if ( (extent_list != NULL) &&
+ (mlock(extent_list, nr_extents*sizeof(unsigned long)) != 0) )
{
PERROR("Could not lock memory for Xen hypercall");
goto out1;
if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 )
{
fprintf(stderr, "Dom_mem operation failed (rc=%ld errno=%d)-- need to"
- " rebuild the user-space tool set?\n",ret,errno);
- goto out2;
+ " rebuild the user-space tool set?\n",ret,errno);
+ }
+
+ if ( extent_list != NULL )
+ {
+ errno_saved = errno;
+ (void)munlock(extent_list, nr_extents*sizeof(unsigned long));
+ errno = errno_saved;
}
- out2: (void)munlock(extent_list, nr_extents*sizeof(unsigned long));
- out1: return ret;
+ out1:
+ return ret;
}
static inline int do_mmuext_op(
{
privcmd_hypercall_t hypercall;
long ret = -EINVAL;
-
+ int errno_saved;
+
hypercall.op = __HYPERVISOR_mmuext_op;
hypercall.arg[0] = (unsigned long)op;
hypercall.arg[1] = (unsigned long)nr_ops;
{
fprintf(stderr, "Dom_mem operation failed (rc=%ld errno=%d)-- need to"
" rebuild the user-space tool set?\n",ret,errno);
- goto out2;
}
- out2: (void)munlock(op, nr_ops*sizeof(*op));
- out1: return ret;
+ errno_saved = errno;
+ (void)munlock(op, nr_ops*sizeof(*op));
+ errno = errno_saved;
+
+ out1:
+ return ret;
}
#define TRC_DOM0OP_ENTER_BASE 0x00020000
#define TRC_DOM0OP_LEAVE_BASE 0x00030000
-extern unsigned int alloc_new_dom_mem(struct domain *, unsigned int);
-
static int msr_cpu_mask;
static unsigned long msr_addr;
static unsigned long msr_lo;
#define TRC_DOM0OP_ENTER_BASE 0x00020000
#define TRC_DOM0OP_LEAVE_BASE 0x00030000
-extern unsigned int alloc_new_dom_mem(struct domain *, unsigned int);
-
static int msr_cpu_mask;
static unsigned long msr_addr;
static unsigned long msr_lo;
#include <xen/physdev.h>
#include <public/sched_ctl.h>
-extern unsigned int alloc_new_dom_mem(struct domain *, unsigned int);
extern long arch_do_dom0_op(dom0_op_t *op, dom0_op_t *u_dom0_op);
extern void arch_getdomaininfo_ctxt(
struct exec_domain *, full_execution_context_t *);
case DOM0_CREATEDOMAIN:
{
- struct domain *d;
- unsigned int pro;
- domid_t dom;
+ struct domain *d;
+ unsigned int pro;
+ domid_t dom;
+ struct exec_domain *ed;
+ unsigned int i, ht, cnt[NR_CPUS] = { 0 };
+
dom = op->u.createdomain.domain;
if ( (dom > 0) && (dom < DOMID_FIRST_RESERVED) )
break;
}
else if ( (ret = allocate_domid(&dom)) != 0 )
- break;
-
- if ( op->u.createdomain.cpu == -1 )
{
- /* Do an initial placement. Pick the least-populated CPU. */
- struct domain *d;
- struct exec_domain *ed;
- unsigned int i, ht, cnt[NR_CPUS] = { 0 };
-
- read_lock(&domlist_lock);
- for_each_domain ( d ) {
- for_each_exec_domain ( d, ed )
- cnt[ed->processor]++;
- }
- read_unlock(&domlist_lock);
-
- /* If we're on a HT system, we only use the first HT for dom0,
- other domains will all share the second HT of each CPU.
- Since dom0 is on CPU 0, we favour high numbered CPUs in
- the event of a tie */
- ht = opt_noht ? 1 : ht_per_core;
- pro = ht-1;
- for ( i = pro; i < smp_num_cpus; i += ht )
- if ( cnt[i] <= cnt[pro] )
- pro = i;
+ break;
}
- else
- pro = op->u.createdomain.cpu % smp_num_cpus;
+
+ /* Do an initial CPU placement. Pick the least-populated CPU. */
+ read_lock(&domlist_lock);
+ for_each_domain ( d )
+ for_each_exec_domain ( d, ed )
+ cnt[ed->processor]++;
+ read_unlock(&domlist_lock);
+
+ /*
+ * If we're on a HT system, we only use the first HT for dom0, other
+ * domains will all share the second HT of each CPU. Since dom0 is on
+ * CPU 0, we favour high numbered CPUs in the event of a tie.
+ */
+ ht = opt_noht ? 1 : ht_per_core;
+ pro = ht-1;
+ for ( i = pro; i < smp_num_cpus; i += ht )
+ if ( cnt[i] <= cnt[pro] )
+ pro = i;
ret = -ENOMEM;
if ( (d = do_createdomain(dom, pro)) == NULL )
break;
- ret = alloc_new_dom_mem(d, op->u.createdomain.memory_kb);
- if ( ret != 0 )
- {
- domain_kill(d);
- break;
- }
-
ret = 0;
op->u.createdomain.domain = d->id;
}
break;
- case DOM0_SETDOMAININITIALMEM:
- {
- struct domain *d;
- ret = -ESRCH;
- d = find_domain_by_id(op->u.setdomaininitialmem.domain);
- if ( d != NULL )
- {
- /* should only be used *before* domain is built. */
- if ( !test_bit(DF_CONSTRUCTED, &d->d_flags) )
- ret = alloc_new_dom_mem(
- d, op->u.setdomaininitialmem.initial_memkb );
- else
- ret = -EINVAL;
- put_domain(d);
- }
- }
- break;
-
case DOM0_SETDOMAINMAXMEM:
{
struct domain *d;
ret = -ESRCH;
- d = find_domain_by_id( op->u.setdomainmaxmem.domain );
+ d = find_domain_by_id(op->u.setdomainmaxmem.domain);
if ( d != NULL )
{
- d->max_pages =
- (op->u.setdomainmaxmem.max_memkb+PAGE_SIZE-1)>> PAGE_SHIFT;
+ d->max_pages = op->u.setdomainmaxmem.max_memkb >> (PAGE_SHIFT-10);
put_domain(d);
ret = 0;
}
struct pfn_info *page;
unsigned long i;
- if ( unlikely(!array_access_ok(extent_list, nr_extents,
- sizeof(*extent_list))) )
+ if ( (extent_list != NULL) &&
+ !array_access_ok(extent_list, nr_extents, sizeof(*extent_list)) )
return start_extent;
if ( (extent_order != 0) && !IS_CAPABLE_PHYSDEV(current->domain) )
}
/* Inform the domain of the new page's machine address. */
- if ( unlikely(__put_user(page_to_pfn(page), &extent_list[i]) != 0) )
+ if ( (extent_list != NULL) &&
+ (__put_user(page_to_pfn(page), &extent_list[i]) != 0) )
return i;
}
struct pfn_info *page;
unsigned long i, j, mpfn;
- if ( unlikely(!array_access_ok(extent_list, nr_extents,
- sizeof(*extent_list))) )
+ if ( !array_access_ok(extent_list, nr_extents, sizeof(*extent_list)) )
return start_extent;
for ( i = start_extent; i < nr_extents; i++ )
}
-unsigned int alloc_new_dom_mem(struct domain *d, unsigned int kbytes)
-{
- unsigned int alloc_pfns, nr_pages;
- struct pfn_info *page;
-
- nr_pages = (kbytes + ((PAGE_SIZE-1)>>10)) >> (PAGE_SHIFT - 10);
- d->max_pages = nr_pages; /* this can now be controlled independently */
-
- /* Grow the allocation if necessary. */
- for ( alloc_pfns = d->tot_pages; alloc_pfns < nr_pages; alloc_pfns++ )
- {
- if ( unlikely((page = alloc_domheap_page(d)) == NULL) )
- {
- domain_relinquish_resources(d);
- return list_empty(&page_scrub_list) ? -ENOMEM : -EAGAIN;
- }
-
- /* Initialise the machine-to-phys mapping for this page. */
- set_machinetophys(page_to_pfn(page), alloc_pfns);
- }
-
- return 0;
-}
-
-
/* Release resources belonging to task @p. */
void domain_destruct(struct domain *d)
{
dummy();
}
-// see alloc_new_dom_mem() in common/domain.c
#define set_machinetophys(_mfn, _pfn) do { } while(0);
#ifdef MEMORY_GUARD
#define DOM0_CREATEDOMAIN 8
typedef struct {
- /* IN parameters. */
- memory_t memory_kb;
- u32 cpu;
/* IN/OUT parameters. */
- /* If 0, domain is allocated. If non-zero use it unless in use. */
- domid_t domain;
- /* OUT parameters. */
+ /* Identifier for new domain (auto-allocate if zero is specified). */
+ domid_t domain;
} dom0_createdomain_t;
#define DOM0_DESTROYDOMAIN 9
dom0_shadow_control_stats_t stats;
} dom0_shadow_control_t;
-#define DOM0_SETDOMAININITIALMEM 27
-typedef struct {
- /* IN variables. */
- domid_t domain;
- memory_t initial_memkb;
-} dom0_setdomaininitialmem_t;
-
#define DOM0_SETDOMAINMAXMEM 28
typedef struct {
/* IN variables. */
dom0_pcidev_access_t pcidev_access;
dom0_sched_id_t sched_id;
dom0_shadow_control_t shadow_control;
- dom0_setdomaininitialmem_t setdomaininitialmem;
dom0_setdomainmaxmem_t setdomainmaxmem;
dom0_getpageframeinfo2_t getpageframeinfo2;
dom0_add_memtype_t add_memtype;